import { isProxy, toRaw } from 'vue'
import { defineStore } from 'pinia'
import http from '@/helpers/http'
import { clone } from '../helpers/utils'

/**
 * Store managing form configuration options
 *
 * Allow to load form_config information through rest
 *
 * form_config can have sections, actions, options, schemas
 */
const getFormConfigStore = (name) =>
  defineStore({
    id: name + 'FormConfig',
    state: () => ({
      options: {},
      sections: {},
      actions: {},
      schemas: {},
      url: '',
    }),
    actions: {
      setUrl(url) {
        const current_base = new URL(window.location.href).origin
        let urlObj = new URL(url, current_base)
        this.url = urlObj.toString()
      },
      /**
       * Load form configuration from the rest api (endi standard is <contextUrl>?form_config=1)
       *
       * @param {*} url : Optionnal form_config url (default to current with ?form_config=1)
       * @returns a Promise resolving to the loaded form configuration
       */
      async loadConfig() {
        console.log(`Loading form config from ${this.url}`)
        return http.get(this.url).then((config) => {
          console.log('Got the configuration')
          console.log(config)
          this.options = config.options || {}
          this.sections = config.sections || {}
          this.actions = config.actions || {}
          this.schemas = config.schemas || {}
          return config
        })
      },
    },
    getters: {
      /**
       * Getter to access a specific option
       *
       * @param {String} The options name
       * @returns {Object} A clone of the given options
       */
      getOptions(state) {
        return (key) => {
          let result = state.options[key]
          return clone(result)
        }
      },
      /**
       *
       * Return the form section description
       * @param {String} section_name: The name of the section can be a path of attributes separated by ':'
       * @returns {*} The section definition
       */
      getSection(state) {
        return (sectionName) => {
          const sections = sectionName.split(':')
          let result = state.sections
          for (let section_name of sections) {
            if (section_name in result) {
              result = result[section_name]
            } else {
              result = null
            }
          }
          return result
        }
      },
      /**
       * Return a Yup Schema generated from a jsonschema
       * @param {String} formName The name of the form we look for
       * @returns
       */
      getSchema(state) {
        return (formName) => {
          let jsonSchema = state.schemas[formName]
          if (isProxy(jsonSchema)) {
            jsonSchema = toRaw(jsonSchema)
          }
          return jsonSchema
        }
      },
    },
  })
export default getFormConfigStore
